home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include "global.h"
- #include "mbuf.h"
- #include "ax25.h"
- #include "timer.h"
- #include "lapb.h"
- #include "trace.h"
- #include "socket.h"
-
- static char *decode_type __ARGS((int16 type));
-
- /* Dump an AX.25 packet header */
- void ax25_dump(fp,bpp,check)
- FILE *fp;
- struct mbuf **bpp;
- int check; /* Not used */
- {
- char tmp[AXBUF];
- char frmr[3];
- char control,pid,seg;
- int16 type;
- int unsegmented;
- struct ax25 hdr;
- char *hp;
-
- fprintf(fp,"AX25: ");
- /* Extract the address header */
- if(ntohax25(&hdr,bpp) < 0){
- /* Something wrong with the header */
- fprintf(fp," bad header!\n");
- return;
- }
- fprintf(fp,"%s",pax25(tmp,hdr.source));
- fprintf(fp,"->%s",pax25(tmp,hdr.dest));
- if(hdr.ndigis > 0){
- fprintf(fp," v");
- for(hp = hdr.digis[0]; hp < &hdr.digis[hdr.ndigis][0];
- hp += AXALEN){
- /* Print digi string */
- fprintf(fp," %s%s",pax25(tmp,hp),
- (hp[ALEN] & REPEATED) ? "*":"");
- }
- }
- if(pullup(bpp,&control,1) != 1)
- return;
-
- fputc(' ',fp);
- type = ftype(control);
- fprintf(fp,"%s",decode_type(type));
- /* Dump poll/final bit */
- if(control & PF){
- switch(hdr.cmdrsp){
- case LAPB_COMMAND:
- fprintf(fp,"(P)");
- break;
- case LAPB_RESPONSE:
- fprintf(fp,"(F)");
- break;
- default:
- fprintf(fp,"(P/F)");
- break;
- }
- }
- /* Dump sequence numbers */
- if((type & 0x3) != U) /* I or S frame? */
- fprintf(fp," NR=%d",(control>>5)&7);
- if(type == I || type == UI){
- if(type == I)
- fprintf(fp," NS=%d",(control>>1)&7);
- /* Decode I field */
- if(pullup(bpp,&pid,1) == 1){ /* Get pid */
- if(uchar(pid) == PID_SEGMENT){
- unsegmented = 0;
- pullup(bpp,&seg,1);
- fprintf(fp,"%s remain %u",seg & SEG_FIRST ?
- " First seg;" : "",seg & SEG_REM);
- if(seg & SEG_FIRST)
- pullup(bpp,&pid,1);
- } else
- unsegmented = 1;
-
- switch(uchar(pid)){
- case PID_SEGMENT:
- fputc('\n',fp);
- break; /* Already displayed */
- case PID_ARP:
- fprintf(fp," pid=ARP\n");
- arp_dump(fp,bpp);
- break;
- case PID_NETROM:
- fprintf(fp," pid=NET/ROM\n");
- netrom_dump(fp,bpp);
- break;
- case PID_IP:
- fprintf(fp," pid=IP\n");
- /* Don't verify checksums unless unsegmented */
- ip_dump(fp,bpp,unsegmented);
- break;
- case PID_X25:
- fprintf(fp," pid=X.25\n");
- break;
- case PID_TEXNET:
- fprintf(fp," pid=TEXNET\n");
- break;
- case PID_NO_L3:
- fprintf(fp," pid=Text\n");
- break;
- default:
- fprintf(fp," pid=0x%x\n",uchar(pid));
- }
- }
- } else if(type == FRMR && pullup(bpp,frmr,3) == 3){
- fprintf(fp,": %s",decode_type(ftype(frmr[0])));
- fprintf(fp," Vr = %d Vs = %d",(frmr[1] >> 5) & MMASK,
- (frmr[1] >> 1) & MMASK);
- if(frmr[2] & W)
- fprintf(fp," Invalid control field");
- if(frmr[2] & X)
- fprintf(fp," Illegal I-field");
- if(frmr[2] & Y)
- fprintf(fp," Too-long I-field");
- if(frmr[2] & Z)
- fprintf(fp," Invalid seq number");
- fputc('\n',fp);
- } else
- fputc('\n',fp);
-
- }
- static char *decode_type(type)
- int16 type;
- {
- switch(uchar(type)){
- case I:
- return "I";
- case SABM:
- return "SABM";
- case DISC:
- return "DISC";
- case DM:
- return "DM";
- case UA:
- return "UA";
- case RR:
- return "RR";
- case RNR:
- return "RNR";
- case REJ:
- return "REJ";
- case FRMR:
- return "FRMR";
- case UI:
- return "UI";
- default:
- return "[invalid]";
- }
- }
-
- /* Return 1 if this packet is directed to us, 0 otherwise. Note that
- * this checks only the ultimate destination, not the digipeater field
- */
- int ax_forus(iface,bp)
- struct iface *iface;
- struct mbuf *bp;
- {
- struct mbuf *bpp;
- char dest[AXALEN];
-
- /* Duplicate the destination address */
- if(dup_p(&bpp,bp,0,AXALEN) != AXALEN){
- free_p(bpp);
- return 0;
- }
- if(pullup(&bpp,dest,AXALEN) < AXALEN)
- return 0;
- if(addreq(dest,iface->hwaddr))
- return 1;
- else
- return 0;
- }
-
-